1. МНОГОКЛАССОВЫЕ ПРОГРАММЫ
Класс - структура, состоящая из полей и методов. Поля хранят какие-либо значения, а методы позволяют к ним обращаться и проводить над ними необходимые манипуляции.
Объект – это созданный на основе класса экземпляр класса. Программа работает с созданными из классов объектами.
Одни классы могут создаваться на основе других, ранее созданных классов. Класс потомок, созданный на основе родительского класса (называемого суперклассом), наследует поля и методы родителя. В классе потомка родительские методы могут быть переопределены или перегружены.
Переопределенный (полиморфный) метод – метод с таким же названием и параметрами, но разным программным кодом. Перегруженный метод – метод с таким же названием и другими параметрами, разным программным кодом.
Класс имеет один или несколько методов-конструкторов, один из которых автоматически вызывается при создании объекта из класса. Класс может иметь секцию инициализации, также автоматически исполняемой при создании объекта из класса.
1.1. ПРИМЕРЫ ПРОСТЕЙШИХ МНОГОКЛАССОВЫХ ПРОГРАММ
1.1.1. Пример консольной программы с одним классом
решения квадратного уравнения
package tsn01.demo_sc;
import java.util.Scanner;
public class App1 {
public static void main(String[] args) {
// Вычисление квадратного уравнения
double a, b, c; // Входные переменные
QuEq eq = new QuEq(); // Создаем объект, решающий квадратное уравнение
try {
Scanner sc = new Scanner(System.in); //Создаем объект для ввода данных с консоли
System.out.println("Решение квадратного уравнения");
System.out.print("Введите a="); a = sc.nextDouble(); // Ввод значения a
System.out.print("Введите b="); b = sc.nextDouble(); // Ввод значения b
System.out.print("Введите c="); c = sc.nextDouble(); // Ввод значения c
if (eq.Calc(a, b, c) == true) { // Если есть решение, то
System.out.format("x1=%.3f%nx2= %.3f%n", eq.x1, eq.x2); // Вывод ответа
} else { System.out.println("Нет решения!"); } // Если нет решения, то сообщение об этом
} catch (Exception e) {}
}
}
class QuEq { // Класс "Квадратное уравнение"
private double a, b, c; // Входные переменные
public double x1, x2; // Искомые значения
private double d; // Дискриминант
QuEq() { a = 0; b = 0; c = 0; d = 0; x1 = 0; x2 = 0; } // Конструктор класса
public boolean Calc(double a, double b, double c) { // Метод класса для расчета
this.a = a; this.b = b; this.c = c;
d = (b * b) - 4 * a * c;
try {
x1 = (-b + Math.sqrt(d)) / (2 * a); // x1
x2 = (-b - Math.sqrt(d)) / (2 * a); // x2
if (!(Double.isNaN(x1)) && (!Double.isInfinite(x1))
&& (!(Double.isNaN(x2)) && (!Double.isInfinite(x2)))) {
return true; } else { return false; }
} catch (Exception e) { return false; }
}
}
1.1.2. Различие между конструкторами и методами в классе
package tsn.utils;
class MyClass {
public MyClass() { // Это конструктор
System.out.println("This is constructor");
}
public void MyClass() { А это метод с таким же названием, разница в возвращаемом значении (void)
System.out.println("This is metod");
}
}
public class MainClass {
public static void main(String[] args) {
MyClass mc = new MyClass(); // Создание объекта класса и вызов его конструктора
mc.MyClass(); // Вызов метода класса
}
}
1.2. СОЗДАНИЕ ДОПОЛНИТЕЛЬНЫХ КЛАССОВ В ПРОГРАММАХ
В многоклассовых программах несколько классов могут храниться в одном файле с расширением «java», но более правильно хранить каждый класс в отдельном файле. Рассмотрим создание новых классов в отдельных файлах программы.
Для добавления в программу новых классов, необходимо вызвать правой кнопкой мыши контекстное меню на имени пакета, выбрать опцию «Новый» - «Класс Java»:

Далее необходимо указать желаемое имя для класса, который нужно создать (имя пакета изменять не нужно):

Заготовка класса готова, теперь нужно вписать в нее нужный код:

1.3. ПРИМЕР КОНСОЛЬНОЙ ПРОГРАММЫ С НЕСКОЛЬКИМИ КЛАССАМИ
(МОДЕЛЬ «СОБАКА - БОЛЬШАЯ СОБАКА - ЩЕНОК»)

1.3.1. Главный класс «App1»
package tsn01.oop;
public class App1 {
public static void main(String[] args) {
// Работа с классами и объектами
BigDog d1 = new BigDog(); // СОЗДАНИЕ ОБЪЕКТА КЛАССА "BigDog"
BigDog d2 = new BigDog("TSN", 100, 26); // СОЗДАНИЕ ОБЪЕКТА КЛАССА "BigDog"
BigDog d3 = new BigDog("TSN", 11, 28); // СОЗДАНИЕ ОБЪЕКТА КЛАССА "BigDog"
d3.dog_aging(); // Вызов метода объекта
System.out.println(d1.name); // Выдаст на экран: "BigDog"
System.out.println(d1.year); // Выдаст на экран: "5"
System.out.println(d1.weight); // Выдаст на экран: "10"
System.out.println(d2.name); // Выдаст на экран: "TSN"
System.out.println(d2.year); // Выдаст на экран: "50"
System.out.println(d2.weight); // Выдаст на экран: "26"
System.out.println(d3.name); // Выдаст на экран: "Dog_big_old"
System.out.println(d3.year); // Выдаст на экран: "14"
System.out.println(d3.weight); // Выдаст на экран: "28"
System.out.println("Создано собак: " + d1.count); // Выдаст на экран: "Создано собак: 3"
Whelp pd = new Whelp(); // Создаем объект "Щенок" ("Щенок" состоит из 3 объектов)
System.out.println(pd.name); // Выдаст на экран: "Dog"
pd.dg.dog_aging(); // "Состарим отца щенка"
System.out.println(pd.bt.name); // Выдаст на экран: "BigDog"
System.out.println(pd.dg.name); // Выдаст на экран: "Dog_big_old"
System.out.println("Создано собак: " + d1.count); // Выдаст на экран: "Создано собак: 6"
//pd.in_w = 2; // Так нельзя, поле скрытое от прямого доступа
pd.setIn_w(2); // Установка поля "Вес при рождении"
System.out.println(pd.getIn_w()); // Выдаст на экран: "2"
// d1 = ("BigDog", 5, 10) - все параметры по умолчанию
// d2 = ("TSN", 50, 26) - все параметры явно указаны, возраст автоограничен
// d3 = ("Dog_big_old", 14, 28) - все параметры явно указаны, но первые два после переопределены
}
}
1.3.2. Класс « Dog» - «Собака»

package tsn01.oop;
public class Dog { // КЛАСС "СОБАКА"
final static int max_year = 50; // Константа «Максимальное количество лет»
protected String name; // Поле "Имя собаки"
int year; // Поле "Количество лет собаки"
static int count = 0; // Статическое поле, количество созданных объектов собак
private int in_w = 1; // Инкапсулированное (скрытое) поле "Вес при рождении"
Dog() { // Метод-КОНСТРУКТОР по-умолчанию
name = "Dog"; // Задаем значение в поле "Имя собаки"
year = 0; // Задаем значение в поле "Количество лет собаки"
count++; // Увеличиваем число созданных объектов в поле "count"
}
Dog(String n, int y) { // ПЕРЕЗАГРУЗКА метода-конструктора
name = n; // Задаем значение в поле "Имя собаки"
if (y > max_year) { // Проверяем год
year = max_year; // Задаем значение в поле "Количество лет собаки"
} else {
year = y; // Задаем значение в поле "Количество лет собаки"
}
count++; // Увеличиваем число созданных объектов в поле "count"
}
void dog_aging() { // Метод класса: делаем собаку "старой", меняя ей имя и возраст (вес не изменяем)
name = "Dog_old"; // Задаем значение в поле "Имя собаки"
year = 10; // Задаем значение в поле "Количество лет собаки"
}
void yip() { // Метод "лай"
System.out.println("yip"); // Вывод на экран фразы "yip"
}
void setIn_w(int w) { // Установка поля "Вес при рождении"
in_w = w;
}
int getIn_w() { // Считывание поля "Вес при рождении"
return in_w;
}
}
1.3.3. Класс «BigDog» - «Большая собака»

package tsn01.oop;
// КЛАСС "БОЛЬШАЯ СОБАКА"
public class BigDog extends Dog { // НАСЛЕДОВАНИЕ класса от другого класса
int weight; // Новое поле "Вес собаки"
BigDog() { // Метод-КОНСТРУКТОР по-умолчанию
name = "BigDog"; // Задаем значение в поле "Имя собаки"
year = 5; // Задаем значение в поле "Количество лет собаки"
weight = 10; // Задаем значение в поле "Вес собаки"
}
BigDog(String n, int y, int w) { // ПЕРЕЗАГРУЗКА метода-конструктора
super(n, y); // Вызов конструктора СУПЕРКЛАССА (т.е. "Dog(n,y)")
weight = w; // Установка значения у поля
}
void dog_aging() { // ПОЛИМОРФИЗМ (ПЕРЕОПРЕДЕЛЕНИЕ) метода "Старение"
name = "Dog_big_old"; // Задаем значение в поле "Имя собаки"
year = 14; // Задаем значение в поле "Количество лет собаки"
}
void yip() { // ПЕРЕОПРЕДЕЛЕННЫЙ (ПОЛИМОРФНЫЙ) метод "Лай"
System.out.println("yip-yip-yip"); // Вывод на экран фразы "yip"
}
}
1.3.4. Класс «Whelp» - «Щенок»

package tsn01.oop;
public class Whelp extends Dog { // КЛАСС "ЩЕНОК"
public BigDog dg; // Композиция объектов- Объект "Папа"
public BigDog bt; // Композиция объектов- Объект "Мама"
{ // Секция инициализации класса
dg = new BigDog(); // Создаем объект "Папа"
bt = new BigDog(); // Создаем объект "Мама"
}
}
1.4. ПРИМЕР ВИЗУАЛЬНОЙ ПРОГРАММЫ С НЕСКОЛЬКИМИ КЛАССАМИ

1.4.1. Методы окна программы
private void jButton_RandomActionPerformed(java.awt.event.ActionEvent evt) {
// Заполнение случайными числами
for (int i = 0; i < jTable1.getRowCount(); i++) {
jTable1.setValueAt((int) (Math.random() * 11), i, 0);
}
}
private void jButton_TaskActionPerformed(java.awt.event.ActionEvent evt) {
// ВЫПОЛНЕНИЕ ЗАДАНИЯ
// Проверка заполнения таблицы
for (int i = 0; i < jTable1.getRowCount(); i++) {
if (jTable1.getValueAt(i, 0) == null) {
JOptionPane.showMessageDialog(rootPane, "Проверьте правильность заполнения столбца К(i)", "Ошибка ввода", JOptionPane.ERROR_MESSAGE);
return;
}
}
int rowCount = jTable1.getRowCount(); // Количество строк в таблице
int[] inArray = new int[rowCount]; // Создаем исходный массив целых чисел
for (int i = 0; i < rowCount; i++) { // Заполняем исходный массив из первого столбца таблицы
inArray[i] = (int) jTable1.getModel().getValueAt(i, 0);
}
TSN01_Calc ma = new TSN01_Calc(); // СОЗДАЕМ ОБЪЕКТ-РЕШАТЕЛЬ ЗАДАНИЯ !!!
ma.SetMass(inArray); // ПЕРЕДАЕМ В ОБЪЕКТ-РЕШАТЕЛЬ ИСХОДНЫЙ МАССИВ
double[] outArray = ma.GetMass(); // ПОЛУЧАЕМ С ОБЪЕКТА РЕШАТЕЛЯ ЗНАЧЕНИЕ РЕЗУЛЬТИРУЮЩЕГО МАССИВА
for (int i = 0; i < rowCount; i++) { // Заносим во второй столбец таблицы значения из результирующего массива
jTable1.getModel().setValueAt(String.format("%.3f", outArray[i]), i, 1);
}
}
private void jButton_ClearActionPerformed(java.awt.event.ActionEvent evt) {
// Очистка таблицы
for (int i = 0; i < jTable1.getRowCount(); i++) {
for (int j = 0; j < jTable1.getColumnCount(); j++) {
jTable1.setValueAt(null, i, j);
}
}
}
private void jButton_ExitActionPerformed(java.awt.event.ActionEvent evt) {
// Выход из программы
System.exit(0);
}
1.4.2. Методы класса-решателя задания
package tsn.javase.lab10;
import java.util.Arrays; // Библиотека работы с массивами
import static java.lang.Math.*; // Импорт всех математических функций
public class TSN01_Calc { // КЛАСС ВЫЧИСЛЕНИЯ ЗНАЧЕНИЙ
int[] InMass; // Переменная для входного массива целых чисел
double[] OutMass; // Переменная для выходного массива вещественных чисел
int length_OrigMass; // Переменная для длины исходного массива
public void SetMass(int OrigMass[]) { // МЕТОД ДЛЯ ЗАДАНИЯ ИСХОДНЫХ ДАННЫХ
length_OrigMass = OrigMass.length; // Определяем длину исходного массива
// Копируем значения из исходного массива во входной массив
InMass = Arrays.copyOf(OrigMass, length_OrigMass);
OutMass = new double[length_OrigMass]; // Создаем выходной массив
}
public double[] GetMass() { // МЕТОД ВЫЧИСЛЕНИЯ ЗНАЧЕНИЯ
int ki, ki1;
double pr = 1, sum = 0, fk = 1;
for (int i = 0; i < length_OrigMass; i++) { // Цикл по элементам входного массива
try {
fk *= (i + 1); // Расчет факториала
ki = InMass[i]; // Текущее значение элемента входного массива
pr *= ki; // Расчет произведения элементов входного массива
sum += ki; // Расчет суммы элементов входного массива
ki1 = InMass[i - 1]; // Предыдущее значение элемента входного массива
// Вычисление элемента для выходного массива по заданному алгоритму
OutMass[i] = (sqrt(pow(cos(ki), 2)
/ (fk + sin(pow(ki1, 2)))) * pr)
/ sum;
} catch (Exception ex) {
OutMass[i] = Double.NaN; // Присваиваем значение элементу "нет решения"
}
}
return OutMass; // Возвращаем результирующий массив в программу
}
}